package com.fengjue.config.mq;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fengjue.pojo.MailConstants;
import com.fengjue.pojo.MailLog;
import com.fengjue.service.IMailLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class RabbitMQConfig {

    private static final Logger log = LoggerFactory.getLogger(RabbitMQConfig.class);
    @Autowired
    private CachingConnectionFactory cachingConnectionFactory;
    @Autowired
    private IMailLogService mailLogService;

    /**
     * rabbitmq的连接工厂
     *
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {


        RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
        /**
         * 消息确认回调，确认消息是否到达borker
         * void confirm(@Nullable CorrelationData var1, boolean var2, @Nullable String var3);
         * 实现的这个接口
         * @FunctionalInterface
         *     public interface ConfirmCallback {
         *         void confirm(@Nullable CorrelationData data, boolean ack, @Nullable String cause);
         *     }
         * data：消息唯一标识
         * ack：确认结果
         * cause：失败原因
         */
        rabbitTemplate.setConfirmCallback((data, ack, cause) -> {
                    String msgId = data.getId();
                    if (ack) {
                        log.info("{}=====消息发送成功", msgId);
                        mailLogService.update(
                                new UpdateWrapper<MailLog>().set("status", 1).eq("msgId", msgId)
                        );
                    }else{
                        log.error("{}=====消息发送失败", msgId);
                    }
                }
        );

        /** 消息失败回调
         * 实现了这个接口
         *  @FunctionalInterface
         *     public interface ReturnCallback {
         *         void returnedMessage(Message msg, int repCode, String repText, String exchange, String routingKey);
         *     }
         * msg          repCode    repText     exchange  routingKey
         * 消息主题        响应码     响应描述       交换机      路由键
         */
        rabbitTemplate.setReturnCallback(
                (msg,repCode,repText,exchange,routingKey)->{
                    log.error("{}=====消息发送queue失败", msg.getBody());

                }
        );

        return rabbitTemplate;
    }

    @Bean
    public Queue queue() {

        return new Queue(
                MailConstants.MAIL_QUEUE_NAME
        );

    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(MailConstants.MAIL_EXCHANGE_NAME);
    }

    @Bean
    public Binding binding() {
        return BindingBuilder.bind(
                queue()).to(directExchange())
                .with(MailConstants.MAIL_ROUTING_KEY_NAME);
    }


}
